package com.bbcare.comm;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.Map;
import java.util.Random;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;

public class OSSClientUtil {
    private static final Log logger = LogFactory.getLog(OSSClientUtil.class);

    /**
     * //文件保存到服务器上
     *
     * @param file
     * @param path
     *            //path 按业务区分路径
     * @return
     * @throws Exception
     */
    public static String uploadPicture(MultipartFile file, String path, Map<String, Object> fileInfo,boolean flag) throws Exception {
        if (file.getSize() > 1024 * 1024 * 1024) {
            throw new Exception("上传图片大小不能超过1G！");
        }

        // 文件原始名称
        String originalFilename = file.getOriginalFilename();
        // 文件扩展名
        String substring = "";
        int pointPos = originalFilename.lastIndexOf(Constants.dot);
        if (-1 != pointPos) {
            substring = originalFilename.substring(pointPos + 1).toLowerCase();
        }
        // 新文件名称
        String name = SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_IMG_NAME_ID) + Constants.dot + substring;

        String imagePath = null;
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
            imagePath = uploadToAliyun(path, substring, name, inputStream,flag);

            fileInfo.put("fileName", name);
            fileInfo.put("fileType", substring);
            fileInfo.put("filePath", imagePath);
            fileInfo.put("fileSize", file.getSize());
            fileInfo.put("sourceFileName", originalFilename);

            return imagePath;
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            throw new Exception("上传文件出错");
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                throw new Exception("上传文件出错");
            }
        }
    }

    /**
     * 上传文件到阿里云具体实现方法
     *
     * @param path
     *            要存放的路径
     * @param substring
     *            文件后缀
     * @param name
     *            文件名
     * @param inputStream
     *            输入流
     * @return
     * @throws Exception
     */
    private static String uploadToAliyun(String path, String substring, String name, InputStream inputStream,boolean flag)
            throws Exception {
        String ACCESS_ID = PropertiesUtils.getProperty("ACCESS_ID");
        String ACCESS_KEY = PropertiesUtils.getProperty("ACCESS_KEY");
        String bucketName = PropertiesUtils.getProperty("bucketName");
        String key = "";
        String endpoint = PropertiesUtils.getProperty("endpoint");
        if (!StringUtils.isBlank(path)) {
            key = path;
        } else {
            key = PropertiesUtils.getProperty("commonImage");
        }
        String contentType = getcontentType(substring,flag);
        logger.info("substring==" + substring + ", contentType==" + contentType);
        String filePath = Constants.IMG_FILE_HTTP_HEAD + bucketName + "." + endpoint + key + name;
        OSSClient client = null;
        try {
            client = new OSSClient(endpoint, ACCESS_ID, ACCESS_KEY);
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(inputStream.available());
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
            objectMetadata.setContentType(contentType);

            if (!client.doesBucketExist(bucketName)) {
                client.createBucket(bucketName);
            }

            PutObjectResult pp = client.putObject(bucketName, key + name, inputStream, objectMetadata);

            logger.info("-------" + filePath);
            if (pp.getETag() != null) {
                client.shutdown();
                return filePath;
            }
            client.shutdown();
            return filePath;
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            throw new Exception("上传文件出错");
        } finally {
            if (null != client) {
                client.shutdown();
            }
        }
    }

    /**
     * //生成带logo二维码
     *
     * @param logoUrl
     *            二维码logo地址
     * @param content
     *            二维码内容
     * @param path
     *            按业务区分路径
     * @return
     * @throws Exception
     */
    public static String uploadLogoQrCode(String content, String logoUrl, String path, String suffix,boolean flag) throws Exception {
        byte[] logoQRcode = null;
        ByteArrayInputStream inputStream = null;

        Random random = new Random();
        String name = random.nextInt(10000) + System.currentTimeMillis() + "." + suffix;
        String imagePath = null;
        try {
            logoQRcode = ToolUtil.createQrCodeAndLogo(content, logoUrl);
            inputStream = new ByteArrayInputStream(logoQRcode);
            imagePath = uploadToAliyun(path, suffix, name, inputStream,flag);
            return imagePath;
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            throw new Exception("上传文件出错");
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                throw new Exception("上传文件出错");
            }
        }
    }

    /**
     * //生成普通二维码
     *
     * @param file
     * @param path
     *            //path 按业务区分路径
     * @return
     * @throws Exception
     */
    public static String uploadQrCode(String content, String path, String suffix,boolean flag) throws Exception {
        byte[] logoQRcode = null;
        ByteArrayInputStream inputStream = null;

        Random random = new Random();
        String name = random.nextInt(10000) + System.currentTimeMillis() + "." + suffix;
        String imagePath = null;
        try {
            logoQRcode = ToolUtil.createQrCode(content);
            inputStream = new ByteArrayInputStream(logoQRcode);
            imagePath = uploadToAliyun(path, suffix, name, inputStream,flag);
            return imagePath;
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            throw new Exception("上传文件出错");
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                throw new Exception("上传文件出错");
            }
        }
    }

    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     *
     * @param FilenameExtension
     *            文件后缀
     * @return String
     */
    public static String getcontentType(String FilenameExtension,boolean flag) {
    	if(flag) {
    		return "application/octet-stream";
    	}else {
		    if (FilenameExtension.equalsIgnoreCase("bmp")) {
		        return "image/bmp";
		    }
		    if (FilenameExtension.equalsIgnoreCase("gif")) {
		        return "image/gif";
		    }
		    if (FilenameExtension.equalsIgnoreCase("jpeg") || FilenameExtension.equalsIgnoreCase("jpg")
		            || FilenameExtension.equalsIgnoreCase("png")) {
		        return "image/jpeg";
		    }
		    if (FilenameExtension.equalsIgnoreCase("html")) {
		        return "text/html";
		    }
		    if (FilenameExtension.equalsIgnoreCase("txt")) {
		        return "text/plain";
		    }
		    if (FilenameExtension.equalsIgnoreCase("vsd")) {
		        return "application/vnd.visio";
		    }
		    if (FilenameExtension.equalsIgnoreCase("pptx") || FilenameExtension.equalsIgnoreCase("ppt")) {
		        return "application/vnd.ms-powerpoint";
		    }
		    if (FilenameExtension.equalsIgnoreCase("docx") || FilenameExtension.equalsIgnoreCase("doc")) {
		        return "application/msword";
		    }
		    if (FilenameExtension.equalsIgnoreCase("xml")) {
		        return "text/xml";
		    }
		    return "text/plain";
    	}
    }

    /**
     * 文件存在访问权限，获取签名的url访问
     *
     * @return
     * @throws Exception
     */
    public static String getFileSignUrl(String url) throws Exception {
        if (StringUtils.isBlank(url)) {
            return url;
        }
        String bucketName = PropertiesUtils.getProperty("bucketName");
        String ACCESS_ID = PropertiesUtils.getProperty("ACCESS_ID");
        String ACCESS_KEY = PropertiesUtils.getProperty("ACCESS_KEY");
        String endpoint = PropertiesUtils.getProperty("endpoint");
        String expiredTimeStr = PropertiesUtils.getProperty("ACCESS_EXPIRED_TIME");
        int expiredTime = Constants.FILE_ACCESS_AUTHORITY_TIMEOUT;
        if (!StringUtils.isBlank(expiredTimeStr)) {
            expiredTime = Integer.parseInt(expiredTimeStr);
        }

        String filePath = Constants.IMG_FILE_HTTP_HEAD + bucketName + "." + endpoint;
        // 兼容老数据
        if (-1 == url.indexOf(filePath)) {
            return url;
        }
        String key = url.substring(filePath.length());
        Date expires = new Date(new Date().getTime() + 1000 * expiredTime);// 超时时间，默认1小时
        OSSClient client = null;
        try {
            client = new OSSClient(endpoint, ACCESS_ID, ACCESS_KEY);
            if (!client.doesBucketExist(bucketName)) {
                client.shutdown();
                return url;
            }

            GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, key);
            generatePresignedUrlRequest.setExpiration(expires);
            URL newUrl = client.generatePresignedUrl(generatePresignedUrlRequest);
            client.shutdown();

            return newUrl.toString();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new AppException(ErrorCode.IMG_EXCEPTION_GET_SIGN_URL, "获取签名url失败:" + e.getMessage());
        } finally {
            if (null != client) {
                client.shutdown();
            }
        }
    }
}
